/*
 * $Id: ContactLogger.java,v 1.7 2010/05/19 13:17:46 navdeep_mahajan Exp $
 * 
 * Copyright (C) 2008 General Electric Company. All Rights Reserved.
 * 
 * This software is the confidential and proprietary information of the General
 * Electric Company (GE). You shall not disclose this software and shall use it
 * only in accordance with the terms of the license agreement you entered into
 * with GE.
 * 
 * GE MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
 * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
 * NON-INFRINGEMENT. GE SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
 * AS A RESULT OF USING, MODIFYING, OR DISTRIBUTING THIS SOFTWARE OR ITS
 * DERIVATIVES.
 */
package com.ge.healthcare.autosc.common.dbLogger;

import java.net.UnknownHostException;
import java.util.List;

import com.ge.healthcare.autosc.common.ASCLogger;
import com.ge.healthcare.autosc.common.ASCUtil;
import com.ge.healthcare.autosc.common.database.dao.IStepTypeDAO;
import com.ge.healthcare.autosc.common.database.pojo.HstSystemContactInfo;
import com.ge.healthcare.autosc.common.database.pojo.HstSystemContactLogs;
import com.ge.healthcare.autosc.common.util.ApplicationInfo;
import com.ge.healthcare.autosc.common.util.PropertyConstants;
import com.ge.healthcare.autosc.common.util.TimeFormatStandard;

public class ContactLogger extends CommonLogger {
	private static final ThreadLocal<HstSystemContactInfo> threadLocal = new ThreadLocal<HstSystemContactInfo>();

	/**
	 * The constructor is used by spring to update step type information in the
	 * database
	 * 
	 * @throws UnknownHostException
	 *             - Unable to determine host name for the system
	 */
	public ContactLogger(String stepTypeName, IStepTypeDAO stepTypeDAO)
			throws UnknownHostException {
		CommonLogger.stepTypeDAO = stepTypeDAO;
		CommonLogger.stepTypeName = stepTypeName;
		updateStepTypeId(stepTypeName);
	}

	/**
	 * Create HstSystemContactInfo VO for running thread
	 * 
	 * @param ipAddress
	 *            - remote system IP address
	 * @param connectType
	 *            - connection type. Either "http" or "iptds"
	 */
	public static void startLogging(String ipAddress, String connectType) {
		String methodName = "startLogging";
		HstSystemContactInfo systemContactInfo = initSystemContactInfo();
		ASCLogger.debug(ContactLogger.class, methodName, "Entering "
				+ methodName);
		systemContactInfo.setIpAddress(ipAddress);
		systemContactInfo.setConnectType(connectType);
		threadLocal.set(systemContactInfo);
		ASCLogger.debug(ContactLogger.class, methodName,
				"SystemContactInfo object created. Leaving");
	}

	public static boolean hasLoggingStarted() {
		if ((HstSystemContactInfo) threadLocal.get() == null) {
			return false;
		} else {
			return true;
		}
	}

	/**
	 * Adds contact log to the step time VO
	 * 
	 * @param log
	 *            - Log to be added
	 */
	public static void addContactLog(String log) {
		HstSystemContactInfo systemContactInfo = getSystemContactInfo();
		HstSystemContactLogs systemContactLog = new HstSystemContactLogs();
		systemContactLog.setContactLogText(log);
		systemContactLog.setHstSystemContactInfo(systemContactInfo);
		List<HstSystemContactLogs> systemContactLogs = systemContactInfo
				.getHstSystemContactLogs();
		if (ASCUtil.isNullOrEmptyList(systemContactLogs)) {
			systemContactLogs.add(systemContactLog);
		} else {
			HstSystemContactLogs oldLog = systemContactLogs
					.get(systemContactLogs.size() - 1);
			if (oldLog.getContactLogText().length() + LOG_DELIM.length()
					+ log.length() <= oldLog.getMaxLogLength()) {
				oldLog.setContactLogText(new StringBuffer().append(
						oldLog.getContactLogText()).append(LOG_DELIM).append(
						log).toString());
			} else {
				systemContactLogs.add(systemContactLog);
			}
		}
		systemContactInfo.setHstSystemContactLogs(systemContactLogs);
		threadLocal.set(systemContactInfo);
	}

	/**
	 * Added contact log and the system Id
	 */
	public static void addContactLog(String systemId, String log) {
		HstSystemContactInfo systemContactInfo = getSystemContactInfo();
		systemContactInfo.setSystemId(systemId);
		HstSystemContactLogs systemContactLog = new HstSystemContactLogs();
		systemContactLog.setContactLogText(log);
		systemContactLog.setHstSystemContactInfo(systemContactInfo);
		List<HstSystemContactLogs> systemContactLogs = systemContactInfo
				.getHstSystemContactLogs();
		if (ASCUtil.isNullOrEmptyList(systemContactLogs)) {
			systemContactLogs.add(systemContactLog);
		} else {
			HstSystemContactLogs oldLog = systemContactLogs
					.get(systemContactLogs.size() - 1);
			if (oldLog.getContactLogText().length() + LOG_DELIM.length()
					+ log.length() <= oldLog.getMaxLogLength()) {
				oldLog.setContactLogText(new StringBuffer().append(
						oldLog.getContactLogText()).append(LOG_DELIM).append(
						log).toString());
			} else {
				systemContactLogs.add(systemContactLog);
			}
		}
		systemContactInfo.setHstSystemContactLogs(systemContactLogs);
		threadLocal.set(systemContactInfo);
	}

	/**
	 * The method marks the end of logging and sends the message to DBLogger
	 * Queue
	 * 
	 * @param codeId
	 *            - Code ID for closing the step time
	 */
	public static void endLogging(Long codeId) {
		String methodName = "logEndTime";
		ASCLogger.debug(ContactLogger.class, methodName, "Entering "
				+ methodName);
		HstSystemContactInfo systemContactInfo = getSystemContactInfo();
		if (ASCUtil.isNullOrEmptyObject(systemContactInfo)) {
			ASCLogger.error(ContactLogger.class, methodName,
					"systemContactInfo has not been initialized");
			return;
		}
		systemContactInfo.setCodeId(codeId);
		if (logSender == null) {
			ASCLogger.debug(ContactLogger.class, methodName,
					"logSender is null");
		}
		sendLogs(systemContactInfo);
		threadLocal.set(null);
	}

	/**
	 * @param stepTime
	 */
	private static void sendLogs(HstSystemContactInfo systemContactInfo) {
		if ("true".equalsIgnoreCase(ApplicationInfo.getInstance().getProperty(
				PropertyConstants.CONTACT_LOGS_ENABLED, "true"))) {
			CommonLogger.logSender.sendSystemContactInfoLog(systemContactInfo);
		}
	}

	/**
	 * Retrieves step time from thread local
	 * 
	 * @return - step time object
	 */
	public static HstSystemContactInfo getSystemContactInfo() {
		HstSystemContactInfo systemContactInfo = (HstSystemContactInfo) threadLocal
				.get();
		if (ASCUtil.isNullOrEmptyObject(systemContactInfo)) {
			systemContactInfo = initSystemContactInfo();
		}
		return systemContactInfo;
	}

	/**
	 * Copy logs from contactLogger to stepLogger. This assume StepLogger is
	 * configured in your deployed application
	 */
	public static void copyLogsToStepLogger() {
		HstSystemContactInfo systemContactInfo = getSystemContactInfo();
		if (systemContactInfo != null) {
			List<HstSystemContactLogs> systemContactLogs = systemContactInfo
					.getHstSystemContactLogs();
			for (HstSystemContactLogs contactLog : systemContactLogs) {
				StepLogger.addStepLog(contactLog.getContactLogText());
			}
		}
	}

	/**
	 * @return
	 */
	private static HstSystemContactInfo initSystemContactInfo() {
		HstSystemContactInfo systemContactInfo = new HstSystemContactInfo();
		systemContactInfo.setContactTime(TimeFormatStandard.getNowMillis());
		systemContactInfo.setStepTypeId(CommonLogger.stepTypeId);
		threadLocal.set(systemContactInfo);
		return systemContactInfo;
	}
}
